package cn.rukbat.demo3.util;

import org.apache.commons.codec.digest.HmacAlgorithms;
import org.apache.commons.codec.digest.HmacUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import java.nio.charset.StandardCharsets;
import java.util.Base64;
import java.util.concurrent.TimeUnit;

@Component
public class PasswordlessTokenUtil {
    
    @Value("${app.security.resource-secret}")
    private String resourceSecret;
    
    @Value("${app.security.token-expiry}")
    private long tokenExpiry;
    
    @Value("${app.security.timestamp-tolerance}")
    private long timestampTolerance;
    
    @Value("${app.security.pre-shared-key}")
    private String preSharedKey;
    
    /**
     * 生成资源访问Token（免密码）
     */
    public String generateToken(String resourcePath, Long timestamp) {
        String data = resourcePath + "|" + timestamp + "|" + tokenExpiry;
        return generateHmacToken(data);
    }
    
    /**
     * 使用预共享密钥生成Token（用于API调用）
     */
    public String generateTokenWithPSK(String resourcePath, Long timestamp, String clientId) {
        String data = resourcePath + "|" + timestamp + "|" + tokenExpiry + "|" + clientId;
        return generateHmacWithPSK(data);
    }
    
    /**
     * 验证Token
     */
    public boolean validateToken(String token, String resourcePath, Long timestamp) {
        if (!StringUtils.hasText(token) || !StringUtils.hasText(resourcePath) || timestamp == null) {
            return false;
        }
        
        // 验证时间戳
        if (!isTimestampValid(timestamp)) {
            return false;
        }
        
        // 验证Token
        String expectedToken = generateToken(resourcePath, timestamp);
        return expectedToken.equals(token);
    }
    
    /**
     * 验证带预共享密钥的Token
     */
    public boolean validateTokenWithPSK(String token, String resourcePath, Long timestamp, String clientId) {
        if (!StringUtils.hasText(token) || !StringUtils.hasText(resourcePath) || timestamp == null) {
            return false;
        }
        
        // 验证时间戳
        if (!isTimestampValid(timestamp)) {
            return false;
        }
        
        // 验证Token
        String expectedToken = generateTokenWithPSK(resourcePath, timestamp, clientId);
        return expectedToken.equals(token);
    }
    
    /**
     * 验证时间戳有效性
     */
    public boolean isTimestampValid(Long timestamp) {
        if (timestamp == null) {
            return false;
        }
        
        long currentTime = System.currentTimeMillis();
        long timeDifference = Math.abs(currentTime - timestamp);
        
        return timeDifference <= timestampTolerance;
    }
    
    /**
     * 生成HMAC Token
     */
    private String generateHmacToken(String data) {
        HmacUtils hmac = new HmacUtils(HmacAlgorithms.HMAC_SHA_256, resourceSecret);
        byte[] hmacBytes = hmac.hmac(data);
        return Base64.getUrlEncoder().withoutPadding().encodeToString(hmacBytes);
    }
    
    /**
     * 使用预共享密钥生成HMAC
     */
    private String generateHmacWithPSK(String data) {
        HmacUtils hmac = new HmacUtils(HmacAlgorithms.HMAC_SHA_256, preSharedKey);
        byte[] hmacBytes = hmac.hmac(data);
        return Base64.getUrlEncoder().withoutPadding().encodeToString(hmacBytes);
    }
    
    /**
     * 生成客户端ID（简化实现）
     */
    public String generateClientId() {
        return "client_" + System.currentTimeMillis();
    }
    
    /**
     * 获取Token过期时间（秒）
     */
    public long getTokenExpirySeconds() {
        return TimeUnit.MILLISECONDS.toSeconds(tokenExpiry);
    }
}

